﻿using System;
using System.Text;

namespace mklib.json
{
	/// <summary>
	/// Json序列化设置
	/// </summary>
	internal class JsonStringifySetting
	{
		internal string Indent = "\t";
		internal string NewLine = "\n";
		internal string ValueBefore = " ";

		internal string Convert(IJsonValue val)
		{
			return ConvertJson (val, this);
		}

		private static string ConvertJson(IJsonValue val, JsonStringifySetting setting)
		{
			var indent = JsonHelper.RepeatString (setting.Indent, val.Depth);
			switch (val.Type) {
			case JsonValueType.Float:
			case JsonValueType.Int:
				var num = val.ValueOf ();
				if (num is DateTime) {
					long ticks = ((DateTime)num).ToUniversalTime ().Ticks - JsonHelper.JavaScriptTimeStart;
					double f = ticks / (double)10000;
					return String.Format ("{0}{1}", String.Empty, f);
				} else {
					return String.Format ("{0}{1}", String.Empty, num);
				}
			case JsonValueType.Boolean:
				return String.Format ("{0}{1}", String.Empty, val.ValueOf ().ToString ().ToLower ());
			case JsonValueType.Null:
				return String.Format ("{0}null", String.Empty);
			case JsonValueType.String:
				string ss = JsonHelper.FormatString((string)val.ValueOf ());
				return String.Format ("{0}\"{1}\"", String.Empty, ss);
			case JsonValueType.Array:
				JsonValueArray arr = (val as JsonValue).Value as JsonValueArray;
				StringBuilder arrA = new StringBuilder ();
				foreach (IJsonValue v in arr.Data) {
					arrA.AppendFormat (",{2}{1}{0}"
						, ConvertJson (v, setting)
						, indent + setting.Indent
						, setting.NewLine
					);
				}
				if (arrA.Length >= 1 + setting.NewLine.Length) {
					arrA.Remove (0, 1 + setting.NewLine.Length);
					arrA.Insert (0, String.Format ("[{0}", setting.NewLine));
					arrA.Append (String.Format ("{0}{1}]"
						, setting.NewLine
						, JsonHelper.RepeatString (setting.Indent, val.Depth))
					);
				} else {
					arrA.Clear ();
					arrA.Append ("[]");
				}

				return arrA.ToString ();
			case JsonValueType.Object:
				JsonValueObject obj = (val as JsonValue).Value as JsonValueObject;
				StringBuilder arrB = new StringBuilder ();
				foreach (var v in obj.Data) {
					arrB.AppendFormat (",{2}{3}\"{0}\":{4}{1}"
						, v.Key
						, ConvertJson (v.Value, setting)
						, setting.NewLine
						, indent + setting.Indent
						, setting.ValueBefore
					);
				}
				if (arrB.Length >= 1 + setting.NewLine.Length) {
					arrB.Remove (0, 1 + setting.NewLine.Length);
					arrB.Insert (0, String.Format ("{{{0}", setting.NewLine));
					arrB.Append (String.Format ("{0}{1}}}"
						, setting.NewLine
						, JsonHelper.RepeatString (setting.Indent, val.Depth))
					);
				} else {
					arrB.Clear ();
					arrB.Append ("{}");
				}

				return arrB.ToString ();
			}
			throw new JsonParseException ("Unknown Type");
		}
	}
}

